#include "server_function.h"
#include "pthreadpool.h"
#include "cmd_tast.h"
#include <func.h>
#include "epoll_plug.h"
#include "server_cmd.h"
#include "mysql_io.h"
#include "file_transmit.h"
#include "server_regite.h"
#include "server_login.h"
#include "log.h"
#include "user_table.h"
int err1;
//服务端处理客户请求函数

User_table* ut;

int ut_init(void){
    ut = User_table_init();    
    return 0;
}

int server_msg_recv(int fd, int epfd, threadpool* pth,threadpool* tsm_pth) {
    cmd_tast* recv_t = (cmd_tast*)malloc(sizeof(cmd_tast));

    err1 = recv(fd, (char*)recv_t, sizeof(cmd_tast), 0);
    if (err1 == -1) {
        error(0, errno, "recv");
        return -1;
    }
    else if (err1 == 0) {
        printf("User:%d exit\n", fd);
        close(fd);
        epoll_mod(epfd, EPOLL_CTL_DEL, EPOLLIN, fd);
        free(recv_t);
        return -1;
    }
    
    User_table_renew(ut,fd);


    recv_t->peerfd = fd;
    if(recv_t->cmdType == CMD_TYPE_DOWNLOAD || recv_t->cmdType == CMD_TYPE_UPLOAD ||recv_t->cmdType == CMD_TYPE_DOWNLOAD_BG){
        tast_queue_push(tsm_pth->q,recv_t);
        return 0;
    }
    tast_queue_push(pth->q, recv_t);
    return 0;
}

//--------------------------------------------------------------------------------------------------//
//服务端处理新连接用户函数
int server_user_recv(int listenfd, int epfd, MYSQL* p_mysql) {
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len=sizeof(clientaddr);
    memset(&clientaddr,0,clientaddr_len);
    int fd = accept(listenfd,(struct sockaddr*)&clientaddr,&clientaddr_len);
    logConnectInfo(clientaddr);
    printf("user:%d login\n", fd);

    User_table_insert(ut,fd);
    epoll_mod(epfd, EPOLL_CTL_ADD, EPOLLIN, fd);
    return 0;
}
//
//--------------------------------------------------------------------------------------------------//
//命令解析线程池处理函数  本函数比较复杂，谨慎修改
void* threadpool_cmd_function(void* arg) {
    //------------------------------------------------//
    //预处理区
    //cmd任务队列q   tsm任务独立额tsm_q
    //ab_path 绝对路径（可以被命令直接使用）
    //free_flag是否在本函数里free(t),因为t可能还要在其他线程池中使用
    //t是客户端传来的cmd_tast
    tast_queue* q = (tast_queue*)arg;
    cmd_tast* t;

    int t_len = sizeof(cmd_tast);
    MYSQL* p_mysql;
    p_mysql = mysql_disk_connect(MYSQL_IP, MYSQL_PORT, MYSQL_NAME, MYSQL_PASSWD, MYSQL_DB);
    //------------------------------------------------//
    //命令处理区
    while (1) {
        t = (cmd_tast*)tast_queue_pop(q);
        int send_fd = t->peerfd;

        //------------------------------------------------//
            //解析命令区
            //这里会对t的path于content进行解析于修改
        printf("type:%d\n",t->cmdType);
        switch (t->cmdType) {
        case CMD_TYPE_LS:
            t->peerfd = 0;
            logCmdInfo(t);
            cmd_ls(t,p_mysql);
            break;

        case CMD_TYPE_CD:
            t->peerfd = 0;
            logCmdInfo(t);
            cmd_cd(t,p_mysql);
            break;

        case CMD_TYPE_PWD:
            t->peerfd = 0;
            logCmdInfo(t);
            cmd_pwd(t);
            break;

        case CMD_TYPE_MKDIR:
            logCmdInfo(t);
            cmd_mkdir(t,p_mysql);
            break;

        case CMD_TYPE_RMDIR:
            logCmdInfo(t);
            cmd_rmdir(t, p_mysql);
            break;

        case CMD_TYPE_RM:
            logCmdInfo(t);
            cmd_rm(t,p_mysql);
            break;

        case CMD_TYPE_NOTCMD:
            logCmdInfo(t);
            t->peerfd = 0;
            strcpy(t->content, cmd_notcmd());
            break;
        case CMD_TYPE_REGIT1:
            logCmdInfo(t);
            server_regite1(t,p_mysql);          
            break;
        case CMD_TYPE_REGIT2:
            logCmdInfo(t);
             server_regite2(t,p_mysql);
            break;
        case CMD_TYPE_LOGIN1:
            logCmdInfo(t);
            server_login1(t,p_mysql);          
            break;
        case CMD_TYPE_LOGIN2:
            logCmdInfo(t);
            server_login2(t,p_mysql);
            break;

        }
        //------------------------------------------------//
            //回信打包区
        err1 = send(send_fd, (char*)t, t_len, 0);
        if (err1 == -1) {
            error(0, errno, "send");
        }

        free(t);
    }
    return NULL;
}

//文件参数线程池的处理函数
void* threadpool_tsm_function(void* arg) {
    cmd_pool_tast* tast = (cmd_pool_tast*)arg;
    tast_queue* q;
    q = tast->q;
    int tsmfd = tast->tsm_fd;
    MYSQL* p_mysql = tast->p_mysql;
    cmd_tast* t;
    char ab_path[PATH_SIZE] = SERVER_PATH;
     

   

    while (1) {
        t = (cmd_tast*)tast_queue_pop(q);
        printf("type:%d\n",t->cmdType);
        switch (t->cmdType) {
        case CMD_TYPE_DOWNLOAD:
            logCmdInfo(t);
            cmd_download(t, ab_path, tsmfd, p_mysql);
            break;
        case CMD_TYPE_DOWNLOAD_BG:
            cmd_download(t, ab_path, tsmfd, p_mysql);
            break;
        case CMD_TYPE_UPLOAD:
            logCmdInfo(t);
            cmd_upload(t, ab_path, tsmfd, p_mysql);
            break;
        }
    }
}

void* threadpool_del_function(void* arg){

    while(1){
        sleep(1);
        ut->click = (ut->click+1)%WAIT_TIME;
        User_table_close(ut);
    }
    return NULL;

}
